home *** CD-ROM | disk | FTP | other *** search
-
- /*---------------------------------------------------------------*/
- /* vu.c - graphical MIDI note visualisation using BOOPSI classes */
- /* ® 1998 by Christian Buchner */
- /*---------------------------------------------------------------*/
-
- /* Library bases */
-
- struct ExecBase *SysBase;
- struct DosLibrary *DOSBase;
- struct GfxBase *GfxBase;
- struct IntuitionBase *IntuitionBase;
- struct Library *GadToolsBase;
- struct Library *UtilityBase;
- struct Library *CamdBase;
-
- /* Workbench or not? */
-
- BOOL WBMode = FALSE;
-
- /* Prototypes */
-
- LONG ShellInterface(void);
- LONG WBInterface(struct Process *MyProc);
-
- BOOL WindowLayout(struct Screen *scr, WORD *ww, WORD *wh, WORD *minw, WORD *minh, WORD *maxw, WORD *maxh, ULONG *Octaves);
- BOOL CreateOrLayoutGadgets(struct Screen *scr, struct Gadget **FirstGad, struct Gadget **PianoGad, struct Gadget **ChanLedGad, WORD ww, WORD wh, ULONG *Octaves);
-
- LONG PianoMeter(UBYTE *linkname, ULONG Octaves, LONG WinX, LONG WinY);
- void MainLoop(UBYTE *linkname, struct Window *Window, struct Gadget **FirstGad, struct Gadget **PianoGad, struct Gadget **ChanLedGad, struct MidiNode **midi, struct MidiLink **link, ULONG *Octaves);
- BOOL OpenLibs(void);
- void CloseLibs(void);
- LONG DoCustomClassMethod (struct IClass *cl, Msg msg);
- LONG __stdargs Message(UBYTE *Msg,UBYTE *Options,...);
- void __stdargs _XCEXIT(LONG lcode);
-
- /* SPrintf.a */
- APTR __stdargs SPrintf(char *, const char *, ...);
- APTR __stdargs VSprintf(char *, const char *, va_list);
-
-
- /* CAM Library data and protos */
-
- struct MidiNode *CreateMidi(Tag tag, ...);
- BOOL SetMidiAttrs(struct MidiNode *mi, Tag tag, ...);
- struct MidiLink *AddMidiLink(struct MidiNode *mi, LONG type, Tag tag, ...);
- BOOL SetMidiLinkAttrs(struct MidiLink *mi, Tag tag, ...);
-
-
- /* Some defines */
-
- /* the opposite of noteon() */
- #define noteoff(m) ( voicemsg(m,MS_NoteOff) || (voicemsg(m,MS_NoteOn) && (!(m)->mm_Data2)) )
-
- #define offsetof(s, m) (size_t)(&(((s *)0)->m))
- #define MIN(a,b) ((a) <= (b) ? (a) : (b))
- #define elementsof(a) ((sizeof(a) / sizeof(a[0])))
-
-
- /* Intuition structures */
-
- enum
- {
- Menu_Ignore,
- Menu_Link,
- Menu_Save,
- Menu_About,
- Menu_Quit,
- Menu_Release,
- };
-
-
- struct NewMenu VUNewMenu[]=
- {
- /* nm_Type nm_Label nm_CommKey nm_Flags nm_MutualExclude nm_UserData */
- NM_TITLE, "Project", NULL, 0, 0, (APTR)Menu_Ignore,
- NM_ITEM, "MIDI Link...", "L", 0, 0, (APTR)Menu_Link,
- NM_ITEM, "Save Config", "S", 0, 0, (APTR)Menu_Save,
- NM_ITEM, NM_BARLABEL, NULL, 0, 0, (APTR)Menu_Ignore,
- NM_ITEM, "About", "?", 0, 0, (APTR)Menu_About,
- NM_ITEM, NM_BARLABEL, NULL, 0, 0, (APTR)Menu_Ignore,
- NM_ITEM, "Quit", "Q", 0, 0, (APTR)Menu_Quit,
- NM_TITLE, "MIDI", NULL, 0, 0, (APTR)Menu_Ignore,
- NM_ITEM, "Release Notes", "N", 0, 0, (APTR)Menu_Release,
- NM_END, NULL, NULL, 0, 0, (APTR)Menu_Ignore,
- };
-
-
-
- /*--------------*/
- /* Startup code */
- /*--------------*/
-
- LONG __saveds mymain(void)
- {
- LONG ReturnCode;
-
- struct Process *MyProc;
-
- SysBase = *((struct ExecBase**)(0x4));
-
- MyProc = (struct Process*) FindTask(NULL);
-
- if (!MyProc->pr_CLI)
- {
- WBMode = TRUE;
- ReturnCode = WBInterface(MyProc);
- }
- else
- {
- ReturnCode = ShellInterface();
- }
-
- return(ReturnCode);
- }
-
-
-
- /*---------------------*/
- /* Workbench Interface */
- /*---------------------*/
-
- LONG WBInterface(struct Process *MyProc)
- {
- struct WBStartup *wbmsg;
-
- LONG ReturnCode;
-
- WaitPort(&MyProc->pr_MsgPort);
-
- if (wbmsg = (struct WBStartup*)GetMsg(&MyProc->pr_MsgPort))
- {
- if (OpenLibs())
- {
- ReturnCode = PianoMeter("out.0", 5, 100, 200);
-
- CloseLibs();
- }
- Forbid();
- ReplyMsg((struct Message*)wbmsg);
- }
- return(ReturnCode);
- }
-
-
-
- /*-----------------*/
- /* Shell Interface */
- /*-----------------*/
-
- LONG ShellInterface(void)
- {
- LONG ReturnCode = RETURN_ERROR;
-
- UBYTE *linkname = "out.0";
-
- ULONG Octaves = 5;
- LONG WinX = 100;
- LONG WinY = 200;
-
- if (OpenLibs())
- {
- /* CLI argument parsing */
-
- struct ArgArray
- {
- UBYTE *aa_Link;
- ULONG *aa_Octaves;
- ULONG *aa_WinX;
- ULONG *aa_WinY;
- } AA = {NULL, NULL, NULL, NULL};
-
- static UBYTE *Template = "LINK/K,OCT=OCTAVES/K/N,WINX/K/N,WINY/K/N";
- struct RDArgs *RDArgs;
-
- ReturnCode = RETURN_FAIL;
-
- if (RDArgs=ReadArgs(Template, (LONG *)&AA, 0))
- {
- if (AA.aa_Link) linkname = AA.aa_Link;
- if (AA.aa_Octaves) Octaves = *AA.aa_Octaves;
- if (Octaves < 1) Octaves = 1;
- if (Octaves > 11) Octaves = 11;
- if (AA.aa_WinX) WinX= *AA.aa_WinX;
- if (AA.aa_WinY) WinY= *AA.aa_WinY;
-
- ReturnCode = PianoMeter(linkname, Octaves, WinX, WinY);
-
- FreeArgs(RDArgs);
- }
- else
- {
- PrintFault(IoErr(),"vu");
- }
- CloseLibs();
- }
- return(ReturnCode);
- }
-
-
-
- /*-----------------------------------*/
- /* MIDI/Window/Gadget initialisation */
- /*-----------------------------------*/
-
- LONG PianoMeter(UBYTE *linkname, ULONG Octaves, LONG WinX, LONG WinY)
- {
- LONG ReturnCode = RETURN_FAIL;
-
- struct Screen *scr;
- APTR VisualInfo;
- struct Window *Window;
- struct Menu *Menu;
-
- struct Gadget *FirstGad = NULL;
-
- struct Gadget *PianoGad = NULL;
-
- UWORD i;
- struct Gadget *ChanLedGad[16]={ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
-
- WORD ww, wh;
- WORD minw, minh;
- WORD maxw, maxh;
-
- struct MidiNode *midi;
- struct MidiLink *link;
- UBYTE buffer[80];
-
- struct Task *MyTask;
- BYTE OldPri;
-
- if( !_initclasses() )
- {
- Message("Unable to initialize the classes.",NULL);
- }
- else
- {
- if (scr = LockPubScreen(NULL))
- {
- if (!(VisualInfo = GetVisualInfo(scr, TAG_DONE)))
- {
- Message("No visual info!",NULL);
- }
- else
- {
- if (!(WindowLayout(scr, &ww, &wh, &minw, &minh, &maxw, &maxh, &Octaves)))
- {
- Message("Couldn't layout window!",NULL);
- }
- else
- {
- if (!(Window = OpenWindowTags( NULL,
- WA_PubScreen, scr,
- WA_Title, "Piano Meter",
- WA_Left, WinX,
- WA_Top, WinY,
- WA_InnerWidth, (ULONG)ww,
- WA_InnerHeight, (ULONG)wh,
- WA_GimmeZeroZero, TRUE,
- WA_DepthGadget, TRUE,
- WA_SizeGadget, TRUE,
- WA_SizeBBottom, TRUE,
- WA_CloseGadget, TRUE,
- WA_DragBar, TRUE,
- WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_GADGETDOWN|IDCMP_GADGETUP|IDCMP_SIZEVERIFY|IDCMP_NEWSIZE|IDCMP_MENUPICK,
- WA_SimpleRefresh, TRUE,
- WA_NoCareRefresh, TRUE,
- WA_NewLookMenus, TRUE,
- TAG_DONE ) ))
- {
- Message("Couldn't open window!",NULL);
- }
- else
- {
- ww = Window->Width - Window->BorderLeft-Window->BorderRight ;
- wh = Window->Height - Window->BorderTop -Window->BorderBottom;
-
- Window->MinWidth = minw + Window->BorderLeft+Window->BorderRight;
- Window->MinHeight = minh + Window->BorderTop +Window->BorderBottom;
- Window->MaxWidth = maxw + Window->BorderLeft+Window->BorderRight;
- Window->MaxHeight = maxh + Window->BorderTop +Window->BorderBottom;
-
- if (!(Menu=(struct Menu *)CreateMenus(VUNewMenu, TAG_DONE)))
- {
- Message("Failed to create intuition menu.",NULL);
- }
- else
- {
- LayoutMenus(Menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE);
- SetMenuStrip(Window, Menu);
-
- if (!(CreateOrLayoutGadgets(scr, &FirstGad, &PianoGad, ChanLedGad, ww, wh, &Octaves)))
- {
- Message("Couldn't create gadgets!",NULL);
- }
- else
- {
- AddGList(Window,FirstGad,-1,-1,NULL);
- RefreshGList(FirstGad,Window,NULL,-1);
-
- if (!(midi = CreateMidi(
- MIDI_Name, "VU Meters",
- MIDI_RecvSignal, SIGBREAKB_CTRL_E,
- MIDI_MsgQueue, 500,
- MIDI_ErrFilter, CMEF_All,
- TAG_DONE)))
- {
- Message("Cannot create MIDI port!",NULL);
- }
- else
- {
- if (!(link = AddMidiLink(midi, MLTYPE_Receiver,
- MLINK_Name, "VU Meter Link",
- MLINK_Location, linkname,
- MLINK_EventMask, CMF_Note|CMF_Mode,
- MLINK_Comment, "Piano Meter [Input]",
- TAG_DONE)))
- {
- Message("Cannot create link to MIDI interface '%s'",NULL,linkname);
- }
- else
- {
- SPrintf(buffer, "Piano Meter [%s]", linkname);
- SetWindowTitles(Window, buffer, (UBYTE*) ~0);
-
- MyTask = FindTask(NULL);
- OldPri = MyTask->tc_Node.ln_Pri;
- MyTask->tc_Node.ln_Pri = 10;
-
- MainLoop(linkname, Window, &FirstGad, &PianoGad, ChanLedGad, &midi, &link, &Octaves);
- ReturnCode = RETURN_OK;
-
- MyTask->tc_Node.ln_Pri = OldPri;
-
- RemoveMidiLink(link);
- }
- DeleteMidi(midi);
- }
-
- RemoveGList(Window,FirstGad,-1);
-
- DisposeObject(PianoGad);
- PianoGad=NULL;
-
- for (i=0; i<16; i++)
- {
- DisposeObject(ChanLedGad[i]);
- ChanLedGad[i]=NULL;
- }
- }
- ClearMenuStrip(Window);
-
- FreeMenus(Menu);
- }
- CloseWindow(Window);
- }
- }
- FreeVisualInfo(VisualInfo);
- }
- UnlockPubScreen(NULL, scr);
- }
- _freeclasses();
- }
- return(ReturnCode);
- }
-
-
- #define XSPACING 4
- #define INTERSPACING 2
- #define YSPACING 4
-
-
- BOOL WindowLayout(struct Screen *scr, WORD *ww, WORD *wh, WORD *minw, WORD *minh, WORD *maxw, WORD *maxh, ULONG *Octaves)
- {
- BOOL Success = FALSE;
-
- struct gpDomain gpd;
- struct TagItem ti[2];
-
- WORD pw=0, ph=0, pmaxw=0;
- WORD clw=0, clh=0;
-
- /* Get the domain of a ChanLed object */
- gpd.MethodID = GM_DOMAIN;
- gpd.gpd_GInfo = NULL;
- gpd.gpd_RPort = &scr->RastPort;
- gpd.gpd_Which = GDOMAIN_NOMINAL;
- ti[0].ti_Tag = NULL;
- gpd.gpd_Attrs = ti;
- if (DoCustomClassMethod (cl_ChanLed, (Msg)&gpd) == 1)
- {
- clw = gpd.gpd_Domain.Width;
- clh = gpd.gpd_Domain.Height;
- }
-
- /* Get the domain of the Piano object */
- gpd.MethodID = GM_DOMAIN;
- gpd.gpd_GInfo = NULL;
- gpd.gpd_RPort = &scr->RastPort;
- gpd.gpd_Which = GDOMAIN_NOMINAL;
- ti[0].ti_Tag = BOPA_Piano_Octaves;
- ti[0].ti_Data = *Octaves;
- ti[1].ti_Tag = TAG_DONE;
- gpd.gpd_Attrs = ti;
- if (DoCustomClassMethod (cl_Piano, (Msg)&gpd) == 1)
- {
- pw = gpd.gpd_Domain.Width;
- ph = gpd.gpd_Domain.Height;
- }
-
- /* Get the maximum width of a Piano object (11 octaves) */
- ti[0].ti_Data = 11;
- if (DoCustomClassMethod (cl_Piano, (Msg)&gpd) == 1)
- {
- pmaxw = gpd.gpd_Domain.Width;
- }
-
- /* Calculate window width and height*/
- if (16*clw > pw) *ww = XSPACING+16*clw+XSPACING;
- else *ww = XSPACING+pw+XSPACING;
- *wh = YSPACING+clh+INTERSPACING+ph+YSPACING;
-
- /* Calculate minimum width and height */
- *minw = XSPACING+16*clw+XSPACING;
- *minh = *wh;
-
- /* Calculate maximum width and height */
- *maxw = XSPACING+pmaxw+XSPACING;
- *maxh = *wh;
-
- Success=TRUE;
-
- return(Success);
- }
-
-
-
- BOOL CreateOrLayoutGadgets(struct Screen *scr, struct Gadget **FirstGad, struct Gadget **PianoGad, struct Gadget **ChanLedGad, WORD ww, WORD wh, ULONG *Octaves)
- {
- BOOL Success = FALSE;
-
- struct gpDomain gpd;
- struct TagItem ti[2];
-
- WORD pw=0, ph=0;
- WORD clw=0, clh=0;
-
- ULONG gx, gy;
-
- UWORD i;
- struct Gadget *prev;
-
- ULONG OldOctaves = 0;
-
- if (*PianoGad)
- {
- GetAttr(BOPA_Piano_Octaves, *PianoGad, &OldOctaves);
- }
-
- /* Get the domain of a ChanLed object */
- gpd.MethodID = GM_DOMAIN;
- gpd.gpd_GInfo = NULL;
- gpd.gpd_RPort = &scr->RastPort;
- gpd.gpd_Which = GDOMAIN_NOMINAL;
- ti[0].ti_Tag = NULL;
- gpd.gpd_Attrs = ti;
- if (DoCustomClassMethod (cl_ChanLed, (Msg)&gpd) == 1)
- {
- clw = gpd.gpd_Domain.Width;
- clh = gpd.gpd_Domain.Height;
- }
-
- /* Try to fit a piano as large as possible into the window */
-
- *Octaves = 11;
- do
- {
- /* Get the domain of the Piano object */
- gpd.MethodID = GM_DOMAIN;
- gpd.gpd_GInfo = NULL;
- gpd.gpd_RPort = &scr->RastPort;
- gpd.gpd_Which = GDOMAIN_NOMINAL;
- ti[0].ti_Tag = BOPA_Piano_Octaves;
- ti[0].ti_Data = *Octaves;
- ti[1].ti_Tag = TAG_DONE;
- gpd.gpd_Attrs = ti;
- if (DoCustomClassMethod (cl_Piano, (Msg)&gpd) == 1)
- {
- pw = gpd.gpd_Domain.Width;
- ph = gpd.gpd_Domain.Height;
- }
-
- if (XSPACING+pw+XSPACING > ww) (*Octaves)--;
-
- } while (XSPACING+pw+XSPACING > ww);
-
- /* Dispose piano only when no. of octaves changed */
-
- if (*PianoGad)
- {
- if (*Octaves != OldOctaves)
- {
- DisposeObject(*PianoGad);
- *PianoGad=NULL;
- }
- }
-
- /* Create and/or layout the gadgets */
-
- gx = (ULONG)((ww-pw)/2);
- gy = (ULONG)((wh-clh-INTERSPACING-ph)/2)+clh+INTERSPACING;
-
- if (!(*PianoGad))
- {
- if (*FirstGad = *PianoGad = prev = (struct Gadget*)NewObject( cl_Piano, NULL,
- GA_Left, gx,
- GA_Top, gy,
- GA_Width, (ULONG)pw,
- GA_Height, (ULONG)ph,
- GA_Immediate,TRUE,
- GA_RelVerify,TRUE,
- GA_ID,100,
- BOPA_Piano_Octaves, *Octaves,
- TAG_END) )
- {
- Success=TRUE;
- }
- }
- else
- {
- *FirstGad = prev = *PianoGad;
-
- SetAttrs(*PianoGad,
- GA_Left, gx,
- GA_Top, gy,
- GA_Width, (ULONG)pw,
- GA_Height, (ULONG)ph,
- TAG_END );
-
- Success = TRUE;
- }
-
- if (Success)
- {
- for (i=0; i<16; i++)
- {
- gx = (ULONG)((ww-16*clw)/2)+i*clw;
- gy = (ULONG)((wh-clh-YSPACING-ph)/2);
-
- if (!(ChanLedGad[i]))
- {
- if (!(ChanLedGad[i] = prev = (struct Gadget*)NewObject( cl_ChanLed, NULL,
- GA_Left, gx,
- GA_Top, gy,
- GA_Width, (ULONG)clw,
- GA_Height, (ULONG)clh,
- GA_Immediate,TRUE,
- GA_RelVerify,TRUE,
- GA_ID,i,
- BOPA_ChanLed_Channel, (ULONG)i+1,
- BOPA_ChanLed_Enabled, 1L,
- BOPA_ChanLed_Lighted, 0L,
- GA_Previous, prev,
- TAG_END)))
- {
- Success=FALSE;
- break;
- }
- }
- else
- {
- SetAttrs(ChanLedGad[i],
- GA_Left, gx,
- GA_Top, gy,
- GA_Width, (ULONG)clw,
- GA_Height, (ULONG)clh,
- GA_Previous, prev,
- TAG_END );
-
- prev = ChanLedGad[i];
- }
- }
- }
-
- if (!Success)
- {
- if (*PianoGad)
- {
- DisposeObject(*PianoGad);
- *PianoGad=NULL;
- }
-
- for (i=0; i<16; i++)
- {
- if (ChanLedGad[i])
- {
- DisposeObject(ChanLedGad[i]);
- ChanLedGad[i]=NULL;
- }
- }
-
- *FirstGad = NULL;
- }
-
- return(Success);
- }
-
-
-
- #define TAGSIZE 32
-
- UWORD NoteArray[128];
- struct TagItem TagBuffer[TAGSIZE];
- UBYTE ChanUse[16];
-
- void MainLoop(UBYTE *linkname, struct Window *Window, struct Gadget **FirstGad, struct Gadget **PianoGad, struct Gadget **ChanLedGad, struct MidiNode **midi, struct MidiLink **link, ULONG *Octaves)
- {
- UWORD MidKey = (*Octaves/2)*12;
- UWORD Mask = 0xffff;
-
- BOOL Active;
- ULONG signals;
- ULONG gotsignals;
- struct IntuiMessage *imsg;
- ULONG Cl;
- UWORD Co;
- APTR IA;
-
- UBYTE Err;
-
- struct TagItem *tagptr;
- ULONG numtags;
-
- UBYTE NewLink[32];
- UBYTE buffer[80];
-
- Active=TRUE;
-
- memset(NoteArray,0,sizeof(NoteArray));
- memset(ChanUse ,0,sizeof(ChanUse ));
-
- while(Active)
- {
- signals = (1L<<Window->UserPort->mp_SigBit) | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_E;
-
- gotsignals = Wait(signals);
-
- if (gotsignals & (1L<<Window->UserPort->mp_SigBit))
- {
- while(Active && (imsg=(struct IntuiMessage*)GetMsg(Window->UserPort)))
- {
- Cl=imsg->Class;
- Co=imsg->Code;
- IA=imsg->IAddress;
- ReplyMsg((struct Message*)imsg);
-
- if (Cl==IDCMP_CLOSEWINDOW)
- {
- Active=FALSE;
- break;
- }
-
- if (Cl==IDCMP_GADGETDOWN)
- {
- UWORD ID = ((struct Gadget*)IA)->GadgetID;
-
- if (ID < 16)
- {
- ULONG flag;
- UWORD note;
-
- GetAttr(BOPA_ChanLed_Enabled, IA, &flag);
-
- if (flag)
- Mask |= (1<<ID);
- else
- Mask &= (~(1<<ID));
-
- tagptr = TagBuffer;
- numtags = 0;
-
- for (note=0;note<128;note++)
- {
- UWORD key = note-60+MidKey;
-
- if (key < 12* (*Octaves))
- {
- if ((NoteArray[note] & Mask))
- {
- tagptr->ti_Tag = BOPA_Piano_KeyState;
- tagptr->ti_Data = (ULONG)(SETKEY|key);
- tagptr++;numtags++;
- }
- else
- {
- tagptr->ti_Tag = BOPA_Piano_KeyState;
- tagptr->ti_Data = (ULONG)(CLEARKEY|key);
- tagptr++;numtags++;
- }
-
- if (numtags == TAGSIZE-1)
- {
- tagptr->ti_Tag = TAG_END;
- SetGadgetAttrsA(*PianoGad,Window,NULL,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
- }
- }
-
- if (numtags)
- {
- tagptr->ti_Tag = TAG_END;
- SetGadgetAttrsA(*PianoGad,Window,NULL,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
- }
- }
-
- if (Cl==IDCMP_GADGETUP)
- {
- }
-
- if (Cl==IDCMP_SIZEVERIFY)
- {
- }
-
- if (Cl==IDCMP_NEWSIZE)
- {
- WORD ww = Window->Width - Window->BorderLeft-Window->BorderRight ;
- WORD wh = Window->Height - Window->BorderTop -Window->BorderBottom;
-
- RemoveGList(Window,*FirstGad,-1);
-
- EraseRect(Window->RPort, 0, 0, ww-1, wh-1);
-
- if (!(CreateOrLayoutGadgets(Window->WScreen, FirstGad, PianoGad, ChanLedGad, ww, wh, Octaves)))
- {
- Message("Error during gadget layout!",NULL);
- Active=FALSE;
- break;
- }
- else
- {
- /* Gadgets have been re-created */
- /* Now set them to the desired state */
- /* even before redrawing */
-
- UBYTE chn;
- UWORD note;
-
- MidKey = (*Octaves/2)*12;
-
- for (chn=0;chn<16;chn++)
- {
- SetAttrs(ChanLedGad[chn], BOPA_ChanLed_Enabled, (ULONG)( (Mask & (1<<chn)) ? TRUE:FALSE ), TAG_DONE);
- SetAttrs(ChanLedGad[chn], BOPA_ChanLed_Lighted, (ULONG)( ( ChanUse[chn] ) ? TRUE:FALSE ), TAG_DONE);
- }
-
- tagptr = TagBuffer;
- numtags = 0;
-
- for (note=0;note<128;note++)
- {
- UWORD key = note-60+MidKey;
-
- if (key < 12* (*Octaves))
- {
- if ((NoteArray[note] & Mask))
- {
- tagptr->ti_Tag = BOPA_Piano_KeyState;
- tagptr->ti_Data = (ULONG)(SETKEY|key);
- tagptr++;numtags++;
- }
- else
- {
- tagptr->ti_Tag = BOPA_Piano_KeyState;
- tagptr->ti_Data = (ULONG)(CLEARKEY|key);
- tagptr++;numtags++;
- }
-
- if (numtags == TAGSIZE-1)
- {
- tagptr->ti_Tag = TAG_END;
- SetAttrsA(*PianoGad,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
- }
- }
-
- if (numtags)
- {
- tagptr->ti_Tag = TAG_END;
- SetAttrsA(*PianoGad,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
-
- AddGList(Window,*FirstGad,-1,-1,NULL);
- RefreshGList(*FirstGad,Window,NULL,-1);
- }
- }
-
- if (Cl==IDCMP_MENUPICK)
- {
- struct MenuItem *n;
- ULONG pick;
-
- while( (Co != MENUNULL) && Active)
- {
- n = ItemAddress( Window->MenuStrip, (ULONG)Co );
- pick = (ULONG) GTMENUITEM_USERDATA( n );
-
- switch(pick)
- {
- case Menu_Link:
- {
- APTR listreq;
-
- if (!(listreq = AllocListRequest(
- LISTREQ_Window, Window,
- LISTREQ_TitleText, "Select input link",
- TAG_DONE )))
- {
- Message("Couldn't allocate a list requester.",NULL);
- }
- else
- {
- if (linkname != NewLink)
- {
- strncpy(NewLink, (*link)->ml_Location->mcl_Node.ln_Name, sizeof(NewLink));
- NewLink[sizeof(NewLink)-1] = 0;
- }
-
- if (SelectCluster( listreq, NewLink, sizeof(NewLink), TAG_DONE ))
- {
- if (strcmp((*link)->ml_Location->mcl_Node.ln_Name,NewLink))
- {
- struct MidiLink *newlink;
-
- if (!(newlink = AddMidiLink(*midi, MLTYPE_Receiver,
- MLINK_Name, "VU Meter Link",
- MLINK_Location, NewLink,
- MLINK_EventMask, CMF_Note|CMF_Mode,
- MLINK_Comment, "Piano Meter [Input]",
- TAG_DONE)))
- {
- Message("Cannot create link to MIDI interface '%s'",NULL,NewLink);
- }
- else
- {
- UWORD note;
- UBYTE chn;
-
- tagptr = TagBuffer;
- numtags = 0;
-
- RemoveMidiLink( *link );
- FlushMidi( *midi );
-
- *link = newlink;
- linkname = NewLink;
-
- SPrintf(buffer, "Piano Meter [%s]", linkname);
- SetWindowTitles(Window, buffer, (UBYTE*) ~0);
-
- for (note=0;note<128;note++)
- {
- for (chn=0;chn<16;chn++)
- {
- UWORD key = note-60+MidKey;
- UWORD cmsk = 1<<chn;
-
- if (NoteArray[note] & cmsk)
- {
- ChanUse[chn]--;
- if (!ChanUse[chn]) SetGadgetAttrs(ChanLedGad[chn], Window, NULL, BOPA_ChanLed_Lighted, FALSE, TAG_DONE);
-
- NoteArray[note] &= (~cmsk);
-
- if ((key < 12* (*Octaves)) && (Mask & cmsk) && (!(NoteArray[note] & Mask)))
- {
- tagptr->ti_Tag = BOPA_Piano_KeyState;
- tagptr->ti_Data = (ULONG)(CLEARKEY|key);
- tagptr++;numtags++;
-
- if (numtags == TAGSIZE-1)
- {
- tagptr->ti_Tag = TAG_END;
- SetGadgetAttrsA(*PianoGad,Window,NULL,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
- }
- }
- }
- }
- if (numtags)
- {
- tagptr->ti_Tag = TAG_END;
- SetGadgetAttrsA(*PianoGad,Window,NULL,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
- }
- }
- }
- FreeListRequest(listreq);
- }
- }
- break;
-
- case Menu_Save:
- {
- Message("Save Config\nIsn't implemented... eeeh!","Damn");
- }
- break;
-
- case Menu_About:
- {
- Message("Piano Meter\n© 1998 by Christian Buchner\nflowerp@eikon.e-technik.tu-muenchen.de","Cool");
- }
- break;
-
- case Menu_Quit:
- {
- Active = FALSE;
- }
- break;
-
- case Menu_Release:
- {
- UWORD note;
- UBYTE chn;
-
- tagptr = TagBuffer;
- numtags = 0;
-
- for (note=0;note<128;note++)
- {
- for (chn=0;chn<16;chn++)
- {
- UWORD key = note-60+MidKey;
- UWORD cmsk = 1<<chn;
-
- if (NoteArray[note] & cmsk)
- {
- ChanUse[chn]--;
- if (!ChanUse[chn]) SetGadgetAttrs(ChanLedGad[chn], Window, NULL, BOPA_ChanLed_Lighted, FALSE, TAG_DONE);
-
- NoteArray[note] &= (~cmsk);
-
- if ((key < 12* (*Octaves)) && (Mask & cmsk) && (!(NoteArray[note] & Mask)))
- {
- tagptr->ti_Tag = BOPA_Piano_KeyState;
- tagptr->ti_Data = (ULONG)(CLEARKEY|key);
- tagptr++;numtags++;
-
- if (numtags == TAGSIZE-1)
- {
- tagptr->ti_Tag = TAG_END;
- SetGadgetAttrsA(*PianoGad,Window,NULL,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
- }
- }
- }
- }
-
- if (numtags)
- {
- tagptr->ti_Tag = TAG_END;
- SetGadgetAttrsA(*PianoGad,Window,NULL,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
- }
- break;
- }
-
- Co = n->NextSelect;
- }
- }
- }
- }
-
- if (Active && (gotsignals & SIGBREAKF_CTRL_E))
- {
- MidiMsg msg;
-
- tagptr = TagBuffer;
- numtags = 0;
-
- while (GetMidi(*midi,&msg))
- {
- if (noteon(&msg))
- {
- UBYTE chn = msg.mm_Status & MS_ChanBits;
- UWORD note = msg.mm_Data1;
- UWORD key = note-60+MidKey;
- UWORD cmsk = 1<<chn;
-
- if (!(NoteArray[note] & cmsk))
- {
- if (!ChanUse[chn]) SetGadgetAttrs(ChanLedGad[chn], Window, NULL, BOPA_ChanLed_Lighted, TRUE, TAG_DONE);
- ChanUse[chn]++;
-
- if ((key < 12* (*Octaves)) && (Mask & cmsk) && (!(NoteArray[note] & Mask)))
- {
- tagptr->ti_Tag = BOPA_Piano_KeyState;
- tagptr->ti_Data = (ULONG)(SETKEY|key);
- tagptr++;numtags++;
- }
-
- NoteArray[note] |= cmsk;
- }
- }
- else
- {
- if (noteoff(&msg))
- {
- UBYTE chn = msg.mm_Status & MS_ChanBits;
- UWORD note = msg.mm_Data1;
- UWORD key = note-60+MidKey;
- UWORD cmsk = 1<<chn;
-
- if (NoteArray[note] & cmsk)
- {
- ChanUse[chn]--;
- if (!ChanUse[chn]) SetGadgetAttrs(ChanLedGad[chn], Window, NULL, BOPA_ChanLed_Lighted, FALSE, TAG_DONE);
-
- NoteArray[note] &= (~cmsk);
-
- if ((key < 12* (*Octaves)) && (Mask & cmsk) && (!(NoteArray[note] & Mask)))
- {
- tagptr->ti_Tag = BOPA_Piano_KeyState;
- tagptr->ti_Data = (ULONG)(CLEARKEY|key);
- tagptr++;numtags++;
- }
- }
-
- }
- else
- {
- if (modemsg(&msg))
- {
- UBYTE chn = msg.mm_Status & MS_ChanBits;
- UBYTE mode = msg.mm_Data1;
- UWORD note;
- UWORD cmsk = 1<<chn;
-
- if (mode == MM_AllOff)
- {
- for (note=0;note<128;note++)
- {
- UWORD key = note-60+MidKey;
-
- if (NoteArray[note] & cmsk)
- {
- ChanUse[chn]--;
- if (!ChanUse[chn]) SetGadgetAttrs(ChanLedGad[chn], Window, NULL, BOPA_ChanLed_Lighted, FALSE, TAG_DONE);
-
- NoteArray[note] &= (~cmsk);
-
- if ((key < 12* (*Octaves)) && (Mask & cmsk) && (!(NoteArray[note] & Mask)))
- {
- tagptr->ti_Tag = BOPA_Piano_KeyState;
- tagptr->ti_Data = (ULONG)(CLEARKEY|key);
- tagptr++;numtags++;
-
- if (numtags == TAGSIZE-1)
- {
- tagptr->ti_Tag = TAG_END;
- SetGadgetAttrsA(*PianoGad,Window,NULL,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
- }
- }
- }
- }
- }
- }
- }
-
- if (numtags == TAGSIZE-1)
- {
- tagptr->ti_Tag = TAG_END;
- SetGadgetAttrsA(*PianoGad,Window,NULL,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
- }
-
- if (numtags)
- {
- tagptr->ti_Tag = TAG_END;
- SetGadgetAttrsA(*PianoGad,Window,NULL,TagBuffer);
- tagptr = TagBuffer; numtags = 0;
- }
-
- if (Err = GetMidiErr(*midi))
- {
- if (Err & CMEF_MsgErr) Message("MIDI Error: MsgErr!",NULL);
- if (Err & CMEF_BufferFull) Message("MIDI Error: BufferFull!",NULL);
- if (Err & CMEF_SysExFull) Message("MIDI Error: SysExFull!",NULL);
- if (Err & CMEF_ParseMem) Message("MIDI Error: ParseMem!",NULL);
- if (Err & CMEF_RecvErr) Message("MIDI Error: RecvErr!",NULL);
- if (Err & CMEF_RecvOverflow) Message("MIDI Error: RecvOverflow!",NULL);
- if (Err & CMEF_SysExTooBig) Message("MIDI Error: SysExTooBig!",NULL);
- }
- }
-
- if (gotsignals & SIGBREAKF_CTRL_C)
- {
- Active=FALSE;
- }
- }
- }
-
-
-
- BOOL OpenLibs(void)
- {
- BOOL Success=FALSE;
-
- SysBase = *((struct ExecBase**)(0x4));
-
- if (DOSBase=(struct DosLibrary*)OpenLibrary("dos.library",39L))
- {
- if (GfxBase=(struct GfxBase*)OpenLibrary("graphics.library",39L))
- {
- if (IntuitionBase=(struct IntuitionBase*)OpenLibrary("intuition.library",39L))
- {
- if (GadToolsBase=OpenLibrary("gadtools.library", 39L))
- {
- if (UtilityBase=(struct Library*)OpenLibrary("utility.library",39L))
- {
- if (!(CamdBase=OpenLibrary("camd.library",0L)))
- {
- Message("This program requires camd.library!",NULL);
- }
- else
- {
- Success=TRUE;
- }
- }
- }
- }
- }
- }
- if (!Success) CloseLibs();
-
- return(Success);
- }
-
-
- void CloseLibs(void)
- {
- if (CamdBase)
- {
- CloseLibrary(CamdBase);
- CamdBase=NULL;
- }
-
- if (UtilityBase)
- {
- CloseLibrary(UtilityBase);
- UtilityBase=NULL;
- }
-
- if (GadToolsBase)
- {
- CloseLibrary(GadToolsBase);
- GadToolsBase=NULL;
- }
-
- if (IntuitionBase)
- {
- CloseLibrary((struct Library*)IntuitionBase);
- IntuitionBase=NULL;
- }
-
- if (GfxBase)
- {
- CloseLibrary((struct Library*)GfxBase);
- GfxBase=NULL;
- }
-
- if (DOSBase)
- {
- CloseLibrary((struct Library*)DOSBase);
- DOSBase=NULL;
- }
- }
-
-
- /*****************************************************************************/
-
- LONG DoCustomClassMethod (struct IClass *cl, Msg msg)
- {
- LONG (__asm *disp)(register __a0 Class *, register __a2 Object *, register __a1 Msg msg);
- disp = cl->cl_Dispatcher.h_Entry;
- return (*disp)(cl, (Object *) cl, msg);
- }
-
-
- /* Show a message to the user */
-
- LONG __stdargs Message(UBYTE *Msg,UBYTE *Options,...)
- {
- LONG retval;
-
- BOOL req = FALSE;
-
- va_list Arg;
- va_start(Arg,Options);
-
- // if (Options) if (strchr(Options,'|')) req = TRUE;
- if (Options) req = TRUE;
-
- if (IntuitionBase && (WBMode || req))
- {
- struct EasyStruct Req={sizeof(struct EasyStruct),0,"Piano Meter",0, NULL};
-
- if (!Options) Options = "I see";
-
- Req.es_TextFormat=Msg;
- Req.es_GadgetFormat=Options;
-
- retval=EasyRequestArgs(NULL,&Req,0,Arg);
- }
- else
- {
- if (DOSBase)
- {
- VPrintf(Msg,Arg);
- Printf("\n");
-
- retval=0;
- }
- }
- va_end(Arg);
-
- return(retval);
- }
-
-
- /* Standard Exit routine */
-
- void __stdargs _XCEXIT(LONG lcode)
- {
- Message("Task wants to exit, return code %ld\nHolding task!", NULL, lcode);
- Wait(0);
- }
-
-
-
- /* CAM Library stubs */
-
- struct MidiNode *CreateMidi(Tag tag, ...)
- {
- return CreateMidiA((struct TagItem *)&tag );
- }
-
- BOOL SetMidiAttrs(struct MidiNode *mi, Tag tag, ...)
- {
- return SetMidiAttrsA(mi, (struct TagItem *)&tag );
- }
-
- struct MidiLink *AddMidiLink(struct MidiNode *mi, LONG type, Tag tag, ...)
- {
- return AddMidiLinkA(mi, type, (struct TagItem *)&tag );
- }
-
- BOOL SetMidiLinkAttrs(struct MidiLink *mi, Tag tag, ...)
- {
- return SetMidiLinkAttrsA(mi, (struct TagItem *)&tag );
- }
-